package com.wx.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.core.type.TypeReference;
import com.github.pagehelper.PageHelper;
import com.wx.core.process.WxApi;
import com.wx.entity.SysWxuser;
import com.wx.entity.WxResource;
import com.wx.entity.WxResourceExample;
import com.wx.entity.WxVoiceReply;
import com.wx.entity.WxVoiceReplyExample;
import com.wx.flag.KeyWordType;
import com.wx.service.SysWxTokenService;
import com.wx.service.SysWxuserService;
import com.wx.service.WxResourceService;
import com.wx.service.WxVoiceReplyService;
import com.wx.util.JsonUtil;
import com.wx.util.UploaderUtils;
import com.zyht.common.AbsManageBaseController;
import com.zyht.common.bean.PropertiesUtilBean.PropertiesUtils;
import com.zyht.common.util.HttpUtils;
import com.zyht.common.util.Page;
import com.zyht.website.entity.SysUser;

@Controller
@RequestMapping("/admin/voice")
public class WxVoiceReplyController extends AbsManageBaseController{
	
	@Resource
	private WxVoiceReplyService wxVoiceReplyService;
	@Resource
	private WxResourceService wxResourceService;
	@Resource
	private SysWxuserService sysWxuserService;
	@Resource
	private SysWxTokenService sysWxTokenService;
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Value("#{propertiesReader[session_user_key]}")
	private String sessionKey;
	@Value("#{propertiesReader[session_wx_key]}")
	private String session_wx_key;
	
	@RequestMapping("list")
	public String list(Integer currentPage, HttpServletRequest request, Model model){
		if(currentPage==null) currentPage=1;
		String wxid = getWxId(request);
		
		String pageSizeStr = PropertiesUtils.getConfig("paganation_page_size");
		int pageSize = Integer.parseInt(pageSizeStr);
		WxVoiceReplyExample example = new WxVoiceReplyExample();
		example.createCriteria().andWxidEqualTo(wxid);
		int count = this.wxVoiceReplyService.countByExample(example);
		PageHelper.startPage(currentPage, pageSize);
		List<WxVoiceReply> list = this.wxVoiceReplyService.selectByExample(example);
		Page<WxVoiceReply> page = new Page<WxVoiceReply>(count, currentPage, pageSize);
		String bp = getBasePath(request)+"/anon/link?path=";
		for(WxVoiceReply reply : list){
			reply.setLinkUrl(bp+reply.getLinkUrl());
		}
		page.setRecordList(list);
		model.addAttribute("page", page);
		return "basic/voice/list";
	}
	
	@RequestMapping("add")
	public String add(Model model){
		model.addAttribute("bean", new WxVoiceReply());
		return "basic/voice/add";
	}
	
	@RequestMapping("edit")
	public String edit(Integer id, Model model, HttpServletRequest request){
		if(null!=id){
			String sessionKey = PropertiesUtils.getConfig("session_user_key");
			HttpSession session = request.getSession();
			Object sessionUser = session.getAttribute(sessionKey);
			int uid = 0;
			if(null!=sessionUser){
				uid = ((SysUser)sessionUser).getId();
			}
			String wxid = getWxId(request);
			if(null==wxid){
				wxid = "";
			}
			WxVoiceReply bean = this.wxVoiceReplyService.selectByPrimaryKey(id);
			if(bean.getUid()==uid && wxid.equals(bean.getWxid())){
				model.addAttribute("bean", bean);
			}else{
				model.addAttribute("bean", new WxVoiceReply());
			}
		}else{
			model.addAttribute("bean", new WxVoiceReply());
		}
		return "basic/voice/add";
	}
	
	@RequestMapping("persis")
	public String save(@ModelAttribute WxVoiceReply bean, Model model, HttpServletRequest request){
		String wxid = getWxId(request);
		if(null==wxid){
			wxid = "";
		}
		String tempWxid = wxid;
		String sessionKey = PropertiesUtils.getConfig("session_user_key");
		HttpSession session = request.getSession();
		Object sessionUser = session.getAttribute(sessionKey);
		int uid = 0;
		if(null!=sessionUser){
			uid = ((SysUser)sessionUser).getId();
		}
		int userId = uid;
		if(bean.getId()!=null&&bean.getId()>0){
			WxVoiceReply reply = this.wxVoiceReplyService.selectByPrimaryKey(bean.getId());
			this.wxVoiceReplyService.updateByPrimaryKey(bean);
			if(!bean.getLinkUrl().equals(reply.getLinkUrl())){
				//上传微信素材
				wxUpload(bean, request, tempWxid, userId);
			}
		}else{
			
			bean.setCreateTime(new Date());
			bean.setUid(uid);
			bean.setWxid(wxid);
			this.wxVoiceReplyService.insert(bean);
			
			//上传微信素材
			wxUpload(bean, request, tempWxid, userId);
		}
		model.addAttribute("redirect", "admin/voice/list");
		return "message";
	}

	//上传微信素材
	private void wxUpload(WxVoiceReply bean, HttpServletRequest request, String tempWxid, int userId) {
		//新增的音频要上传到微信
		new Thread(){
			@Override
			@SuppressWarnings("unchecked")
			public void run() {
				SysWxuser user = sysWxuserService.selectByWxid(tempWxid);
				String token = sysWxTokenService.getAccessToken(tempWxid, user.getAppid(), user.getAppsecretd());
				String mediaType = "voice";
				WxVoiceReplyExample example = new WxVoiceReplyExample();
				example.createCriteria().andWxidEqualTo(tempWxid).andUidEqualTo(userId)
				.andKeywordsEqualTo(bean.getKeywords()).andTitleEqualTo(bean.getTitle());
				List<WxVoiceReply> voices = wxVoiceReplyService.selectByExample(example);
				WxVoiceReply voice = null;
				if(voices.size()>0)
					voice = voices.get(0);
				if(null==voice){
					return;
				}
				String linkUrl = voice.getLinkUrl();
				linkUrl = UploaderUtils.decodeFilePath(linkUrl);
				byte[] array = null;
				try{
					array = IOUtils.toByteArray(new FileInputStream(linkUrl));
				} catch (FileNotFoundException e1){
					e1.printStackTrace();
				} catch (IOException e1){
					e1.printStackTrace();
				}
				if(null==array){
					logger.error("获取文件["+linkUrl+"]失败！");
					return;
				}
				String fileName = StringUtils.getFilename(linkUrl.replace("\\","/"));
				String uri = WxApi.MATERIAL_UPLOAD;
				uri = String.format(uri, token);
				HttpClient client = new HttpClient();
				HttpConnectionManagerParams params = client.getHttpConnectionManager().getParams();
				params.setConnectionTimeout(5000);
				params.setSoTimeout(5000);
				client.getHttpConnectionManager().setParams(params);
				PostMethod post = new PostMethod(uri);
				try {
					ByteArrayPartSource ps = new ByteArrayPartSource(fileName, array);
					Part[] parts = {new FilePart("media", ps), new StringPart("access_token", token), new StringPart("type", mediaType)};
					MultipartRequestEntity multipartEntity = new MultipartRequestEntity(parts, post.getParams());
					post.setRequestEntity(multipartEntity);
					int code = client.executeMethod(post);
					logger.info("微信上传素材请求状态码是：" + code);
					if(code==HttpStatus.SC_OK){
						String postResponse = post.getResponseBodyAsString();
						logger.info("微信上传素材信息是：" + postResponse);
						Map<String, String> map = (Map<String, String>) JsonUtil.str2map(postResponse, new TypeReference<Map<String, String>>(){});
						String errcode = map.get("errcode"); 
						if(!StringUtils.isEmpty(errcode)){
							logger.warn("微信素材["+linkUrl+"]上传异常，errcode is -->" + errcode);
							return;
						}
						String mediaId = map.get("media_id");
						WxResourceExample reEx = new WxResourceExample();
						reEx.createCriteria().andRefIdEqualTo(voice.getId()).andRefTypeEqualTo(KeyWordType.TYPE_RADIO.getValue());
						wxResourceService.deleteByPrimaryKey(reEx);
						WxResource resource = new WxResource();
						resource.setRefId(voice.getId());
						resource.setRefType(KeyWordType.TYPE_RADIO.getValue());
						resource.setMediaId(mediaId);
						wxResourceService.insert(resource);
						logger.info("微信素材["+linkUrl+"]上传成功>>>");
					}else{
						logger.warn("微信素材["+linkUrl+"]上传异常，返回响应码是【"+code+"】");
					}
				} catch (HttpException e) {
					logger.error("微信Http上传素材请求失败"+e.getMessage());
				} catch (IOException e) {
					logger.error("微信Http上传素材请求IO失败"+e.getMessage());
				}
			};
		}.start();
	}

	@RequestMapping("del")
	public String del(Integer id, HttpServletRequest request, Model model){
		String sessionKey = PropertiesUtils.getConfig("session_user_key");
		HttpSession session = request.getSession();
		Object sessionUser = session.getAttribute(sessionKey);
		int uid = 0;
		if(null!=sessionUser){
			uid = ((SysUser)sessionUser).getId();
		}
		String wxid = getWxId(request);
		if(null==wxid){
			wxid = "";
		}
		WxVoiceReplyExample example = new WxVoiceReplyExample();
		example.createCriteria().andUidEqualTo(uid).andWxidEqualTo(wxid).andIdEqualTo(id);
		WxVoiceReply bean = this.wxVoiceReplyService.selectByPrimaryKey(id);
		if(null!=bean){
			//删除音频资料
			String url = UploaderUtils.decodeFilePath(bean.getLinkUrl());
			Runnable run = () ->{
				File file = new File(url);
				if(file.exists()){
					file.delete();
				}
			};
			new Thread(run).start();
			//微信
			WxResourceExample wxResourceExample = new WxResourceExample();
			wxResourceExample.createCriteria().andRefIdEqualTo(bean.getId()).andRefTypeEqualTo(KeyWordType.TYPE_RADIO.getValue());
			List<WxResource> resourceList = this.wxResourceService.selectByExample(wxResourceExample);
			SysWxuser user = sysWxuserService.selectByWxid(wxid);
			String token = sysWxTokenService.getAccessToken(wxid, user.getAppid(), user.getAppsecretd());
			if(StringUtils.isEmpty(token)){
				model.addAttribute("msg", "公众丢失授权绑定");
				model.addAttribute("redirect", "admin/sysuser/list");
				return "message";
			}
			for(WxResource wxResource : resourceList){
				String mediaId = wxResource.getMediaId();
				Map<String, String> params = new HashMap<String, String>();
				params.put("media_id", mediaId);
				params.put("access_token", token);
				String delRes = HttpUtils.post(WxApi.DEL_MATERIAL, params);
				logger.info("删除永久素材【"+wxResource.getId()+", "+mediaId+"】返回消息： " + delRes);
				wxResourceService.deleteByPrimaryKey(wxResource.getId());
			}
		}
		this.wxVoiceReplyService.deleteByPrimaryKey(example);
		model.addAttribute("redirect", "admin/voice/list");
		return "message";
	}
	
	@RequestMapping("up")
	public String uploadPage(Integer flag, Model model){
		model.addAttribute("flag",flag);
		return "basic/shared/voice_upload";
	}
	
	@RequestMapping("upload")
	public void upload(MultipartFile picture, Integer flag, HttpServletResponse response, HttpServletRequest request){
		String type = picture.getContentType();
		logger.debug("文件上传类型是：" + type);
		//校验文件大小
		long limitSize = 5 * 1024 * 1024; 
		long fileSize = picture.getSize();
		if(fileSize>limitSize){
			logger.warn("上传文件超出限制【5M】，上传失败》》》》");
			writeHtml(response, "<script type='text/javascript'>window.parent.closeWin(null, "+flag+", '音频文件不要超过5M')</script>");
			return;
		}
		
		String appendPath="";
		try {
			appendPath = UploaderUtils.uploadAndReturnApath("voice", picture.getInputStream(), picture.getOriginalFilename(), request);
		} catch (IOException e) {
			logger.error("文件["+picture.getOriginalFilename()+"]上传异常："+e.getMessage());
			writeHtml(response, "<script type='text/javascript'>window.parent.closeWin(null, "+flag+")</script>");
			return;
		}
		
		logger.debug("文件相对路径是:" + appendPath);
		String webUrl = appendPath.replace("\\", "/");
		writeHtml(response, "<script type='text/javascript'>window.parent.closeWin('"+webUrl+"', "+flag+")</script>");
		logger.debug("文件["+picture.getOriginalFilename()+"]上传结束.....");
	}
}
